﻿using System.Collections.Generic;
using System.Linq;
using com.cruxomatic.DTOs;
using com.cruxomatic.BusinessObjects;
using com.cruxomatic.BusinessObjects.DatabaseQueries;
using com.cruxomatic.exceptions;

namespace com.cruxomatic.BusinessFacades
{
    public class CompanyFacade
    {
        public List<CompanyInformation> GetCompanies()
        {
            return GetAllCompaniesEnumerableList().ToList();
        }

        public IEnumerable<CompanyInformation> GetAllCompaniesEnumerableList()
        {
            Queries query = new Queries();
            IEnumerable<CompanyInformation> companies =
                from companyList in query.GetCompanies()
                select ClassConverter.CopyCompanyToCompanyInformation(companyList);
            return companies;
        }
		
		public List<CompanyInformation> GetCompanies(List<int> CompaniesIDs)
        {
            Queries query = new Queries();
            IEnumerable<CompanyInformation> companies = from allcompanies in query.GetCompanies(CompaniesIDs)
                                                        select ClassConverter.CopyCompanyToCompanyInformation(allcompanies);
            return companies.ToList();
        }

        public CompanyInformation GetCompany(int CompanyID)
        {
            if (CompanyID == 0) return new CompanyInformation();
            Queries locationQuery = new Queries();
            Company company = locationQuery.GetCompany(CompanyID);
            return ClassConverter.CopyCompanyToCompanyInformation(company);
        }

        public List<CompanyInformation> GetExternalCompanies()
        {
            Queries companyQuery = new Queries();
            IEnumerable<CompanyInformation> companies = from allcompanies in companyQuery.GetCompaniesByType(CompanyTypeLiterals.ExternalCompany)
                                                        select ClassConverter.CopyCompanyToCompanyInformation(allcompanies);
            return companies.ToList();

        }

        public bool IsCompanyInternal(int CompanyID)
        {
            if (GetCompany(CompanyID).CompanyType == CompanyTypeLiterals.InternalCompany)
                return true;
            return false;
        }

        public bool IsCompanyExternal(int CompanyID)
        {
            if (GetCompany(CompanyID).CompanyType == CompanyTypeLiterals.ExternalCompany)
                return true;
            return false;
        }

        public List<CompanyInformation> GetInternalCompanies()
        {
            Queries companyQuery = new Queries();
            IEnumerable<CompanyInformation> companies = from allcompanies in companyQuery.GetCompaniesByType(CompanyTypeLiterals.InternalCompany)
                                                        select ClassConverter.CopyCompanyToCompanyInformation(allcompanies);
            return companies.ToList();
        }

        public void SaveCompany(CompanyInformation company, int ParentCompany)
        {
            CheckValidity(company);
            Queries query = new Queries();
            Company dbCompany = new Company();
            if (company.CompanyID != 0)
                dbCompany = query.GetCompany(company.CompanyID);
            else if (company.CompanyID == 0 && company.CompanyType == CompanyTypeLiterals.ExternalCompany)
            {
                company.ParentCompanyID = ParentCompany;
            }
            dbCompany = ClassConverter.CopyCompanyInformationToCompany(company, dbCompany);
            
            dbCompany.CompanyMasterLocations = null;
            foreach (var mldb in company.MasterLocations)
            {
                CompanyMasterLocation location = new CompanyMasterLocation();
                dbCompany.CompanyMasterLocations.Add(
                    ClassConverter.CopyCompanyMasterLocationInfoToMasterLocation(mldb,location));
            }
             

            if (company.CompanyID != 0)
                query.SubmitChanges();
            else
                query.InsertCompany(dbCompany);
        }

        private void CheckValidity(CompanyInformation company)
        {

            if (DoesCompanyExist(company))
                throw CruxExceptionManager.CreateNewDatabaseException("901");

        }

        public bool DoesCompanyExist(CompanyInformation company)
        {
            Queries query = new Queries();
            Company dbCompany = query.GetCompany(company.CompanyName);
            if (dbCompany != null && dbCompany.CompanyID != company.CompanyID)
                return true;
            return false;
        }

        public void DeleteCompany(int CompanyID)
        {
            Queries query = new Queries();

            Company company = query.GetCompany(CompanyID);
            IEnumerable<Department> departments = from departmentlist in company.Departments
                                                  select departmentlist;
            query.DeleteDepartments(departments, false);
            query.DeleteCompany(company, false);
            query.SubmitChanges();
        }

        public List<CompanyInformation> GetCompaniesRepresentedBy(int RepresentativeId)
        {
            return GetCompaniesRepresentedByEnumerableList(RepresentativeId).ToList();
        }

        public IEnumerable<CompanyInformation> GetCompaniesRepresentedByEnumerableList(int RepresentativeId)
        {
            Queries query = new Queries();
            IEnumerable<CompanyInformation> companies = from allcompanies in query.GetCompaniesRepresentedBy(RepresentativeId)
                                                        select ClassConverter.CopyCompanyToCompanyInformation(allcompanies);
            return companies;
        }

        public CompanyInformation GetCompany(string CompanyName)
        {
            Queries query = new Queries();
            Company company = query.GetCompany(CompanyName);
            return ClassConverter.CopyCompanyToCompanyInformation(company);
        }

        public List<CompanyInformation> GetAllManagableCompanies(UserInformation user)
        {
            Queries query = new Queries();
            IEnumerable<CompanyInformation> usercompanies = from allcompanies in query.GetCompaniesForUser(user.UserID)
                select allcompanies;

            IEnumerable<CompanyInformation> companies =
                from allcompanies in query.GetChildOrOwnedCompanies(usercompanies.Select(p => p.CompanyID).ToList())
                select allcompanies;


            List<CompanyInformation> companylist = companies.Union(usercompanies).ToList();
            return companylist;
        }
    }
}
